﻿using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System.Net;
using WomanMotion.WebApi.Api.Utility;
using WomanMotion.WebApi.Infrastructure.UnifyResult;
using WomanMotion.WebApi.Model.Dtos.Role;
using WomanMotion.WebApi.Model.Dtos;
using WomanMotion.WebApi.Service;
using WomanMotion.WebApi.Service.IService;
using Microsoft.AspNetCore.Authorization;
using NewLife.Redis.Core;
using NewLife.Configuration;
using WomanMotion.WebApi.Infrastructure.DataBaseCommon;
using WomanMotion.WebApi.Model.Dtos.SysConfig;

namespace WomanMotion.WebApi.Api.Controllers
{
    /// <summary>
    /// 角色管理
    /// </summary>
    [Route("api/[controller]/[action]")]
    [XSSFilter]
    [ApiController]
    [DescriptionName("角色管理", true, 110)]
    public class RoleController : BaseController
    {
        /// <summary>
        /// 角色服务对象
        /// </summary>
        protected readonly IRoleService _role;

        /// <summary>
        /// 用户服务对象
        /// </summary>
        protected readonly IUsersService _users;

        private readonly INewLifeRedis _redisService;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="logger"></param>
        /// <param name="role"></param>
        /// <param name="users"></param>
        public RoleController(ILogger<RoleController> logger, IRoleService role, IUsersService users, INewLifeRedis redisService) : base(logger)
        {
            this._role = role;
            this._users = users;
            _redisService = redisService;
        }

        /// <summary>
        /// 创建角色
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPost]
        [ProducesResponseType(typeof(SwaggerResultTemplate<RoleVM>), (int)HttpStatusCode.OK)]
        [DescriptionName("创建角色", true, "角色管理", "List", "RoleList")]
        public async Task<IResultOutput> Created(CreatedRoleDTO dto)
        {
            var acs = from str in dto.authoritystree where str.Contains("action") select str;
            if (await _role.GetAnyAsync(m => m.Code == dto.Code))
            {
                return ResultOutput.NotOk("存在相同的角色代码,添加失败");
            }
            var res = await _role.CreatedAsync(dto);
            if (res != null)
            {
                //加入缓存
                _redisService.Set("role_ifdisable_" + res.Code, res.Ifdisable.ToString());
                return ResultOutput.Ok(res, "操作成功");
            }
            else
            {
                return ResultOutput.NotOk("添加失败");
            }
        }

        /// <summary>
        /// 启用角色信息
        /// </summary>
        /// <param name="ids">主键ID数组</param>
        /// <returns></returns>
        [HttpPost]
        [ProducesResponseType(typeof(SwaggerResultTemplate), (int)HttpStatusCode.OK)]
        [DescriptionName("启用角色信息")]
        public async Task<IResultOutput> Enable(PrimaryKeyDTO ids)
        {
            var res = await _role.UpdateDisableAsync(DisableEnum.Enable, ids.Ids);
            if (res > 0)
            {
                foreach (var item in ids.Ids)
                {
                    var role = await _role.GetByIdAsync(item);
                    var redisname = "role_ifdisable_" + role.Code;
                    //如果存在缓存先移除
                    _redisService.Remove(redisname);
                    //然后在添加保证是最新
                    _redisService.Set(redisname, "1");
                }
                return ResultOutput.Ok(new object(), "操作成功");
            }
            else
            {
                return ResultOutput.NotOk("操作失败");
            }
        }

        /// <summary>
        /// 禁用角色信息
        /// </summary>
        /// <param name="ids">主键ID数组</param>
        /// <returns></returns>
        [HttpPost]
        [ProducesResponseType(typeof(SwaggerResultTemplate), (int)HttpStatusCode.OK)]
        [DescriptionName("禁用角色信息")]
        public async Task<IResultOutput> Disable(PrimaryKeyDTO ids)
        {
            foreach (var item in ids.Ids)
            {
                var entity = await _role.GetAsync(m => m.Id == item);
                if (entity == null)
                {
                    return ResultOutput.NotOk("操作失败,有角色查询不到");
                }
                if (entity.Code == "admin" || entity.Code == "ordinary")
                {
                    return ResultOutput.NotOk("操作失败,不允许禁用admin或ordinary角色");
                }
                if (await _users.GetAnyAsync(m => m.Roleid == item && m.Ifdisable == 1))
                {
                    return ResultOutput.NotOk("角色:" + item.ToString() + " 存在关联用户禁用失败");
                }
            }
            var res = await _role.UpdateDisableAsync(DisableEnum.Disable, ids.Ids);
            if (res > 0)
            {
                foreach (var item in ids.Ids)
                {
                    var role = await _role.GetByIdAsync(item);
                    var redisname = "role_ifdisable_" + role.Code;
                    //如果存在缓存先移除
                    _redisService.Remove(redisname);
                    //然后在添加保证是最新
                    _redisService.Set(redisname, "0");
                }
                return ResultOutput.Ok(new object(), "操作成功");
            }
            else
            {
                return ResultOutput.NotOk("操作失败");
            }
        }

        /// <summary>
        /// 更新角色信息
        /// </summary>
        /// <param name="dto">dto</param>
        /// <returns>实体信息</returns>
        [HttpPost]
        [ProducesResponseType(typeof(SwaggerResultTemplate<RoleVM>), (int)HttpStatusCode.OK)]
        [DescriptionName("更新角色信息")]
        public async Task<IResultOutput> Update(UpdateRoleDTO dto)
        {
            var entity = await _role.GetAsync(m => m.Id == dto.Id);
            if (entity == null)
            {
                return ResultOutput.NotOk("操作失败,有角色查询不到");
            }
            if (entity.Code == "admin")
            {
                return ResultOutput.NotOk("操作失败,不允许更新admin");
            }
            var res = await _role.UpdateAsync(dto);
            if (res == null)
            {
                return ResultOutput.NotOk("操作失败");
            }
            var redisname = "role_ifdisable_" + res.Code;
            //如果存在缓存先移除
            _redisService.Remove(redisname);
            //然后在添加保证是最新
            _redisService.Set(redisname, res.Ifdisable.ToString());
            return ResultOutput.Ok(res, "操作成功");
        }

        /// <summary>
        /// 根据ID查询角色信息
        /// </summary>
        /// <param name="id">id主键</param>
        /// <returns>实体信息</returns>
        [HttpGet]
        [ProducesResponseType(typeof(SwaggerResultTemplate<RoleVM>), (int)HttpStatusCode.OK)]
        [DescriptionName("根据ID查询角色信息")]
        public async Task<IResultOutput> GetById(long id)
        {
            var res = await _role.GetByIdAsync(id);
            if (res == null)
            {
                return ResultOutput.NotOk("没有数据");
            }
            return ResultOutput.Ok(res, "操作成功");
        }

        /// <summary>
        /// 分页获取角色信息
        /// </summary>
        /// <param name="pars">查询条件</param>
        /// <returns></returns>
        [HttpPost]
        [ProducesResponseType(typeof(SwaggerResultTemplate<PageViewBase<List<RoleVM>>>), (int)HttpStatusCode.OK)]
        [DescriptionName("分页获取角色信息")]
        public async Task<IResultOutput> GetPageList(QueryParameterBase pars)
        {
            var res = await _role.GetPageNavListAsync(pars);
            if (res.Data == null || res.Data.Count == 0)
            {
                return ResultOutput.NotOk("没有数据");
            }
            return ResultOutput.Ok(res, "操作成功");
        }

        /// <summary>
        /// 查询所有角色信息
        /// </summary>
        /// <returns>实体信息</returns>
        [HttpGet]
        [ProducesResponseType(typeof(SwaggerResultTemplate<List<RoleVM>>), (int)HttpStatusCode.OK)]
        [DescriptionName("查询所有角色信息")]
        public async Task<IResultOutput> GetRole()
        {
            var res = await _role.GetListAsync(m => m.Ifdisable == 1);
            if (res.Count == 0)
            {
                return ResultOutput.NotOk("没有数据");
            }
            return ResultOutput.Ok(res, "操作成功");
        }
    }
}